package com.jiayou.handler

import cn.hutool.core.net.NetUtil
import com.jiayou.im.entity.Chat
import com.jiayou.im.service.impl.ChatServiceImpl
import com.jiayou.message.*
import com.jiayou.message.type.DataType
import com.jiayou.message.type.NetWorkType
import com.jiayou.tool.SerializableTool
import io.netty.channel.Channel
import io.netty.channel.ChannelHandlerContext
import io.netty.channel.SimpleChannelInboundHandler
import io.netty.channel.group.ChannelGroup
import sun.net.util.IPAddressUtil
import java.io.ByteArrayInputStream
import java.io.ObjectInputStream
import java.time.LocalDateTime
import java.util.concurrent.ConcurrentHashMap

/**
@author 李 双
@data   2020-11-19  12:43
@info
 */

class ServerMessageChannelHandler(
    var users: ConcurrentHashMap<OnLineMessage, Channel>,
    var channelGroup: ChannelGroup,
    var chatServiceImpl: ChatServiceImpl
) :
    SimpleChannelInboundHandler<ChannelMessage>() {   //设置处理器


    lateinit var id: OnLineMessage

    override fun channelRead0(ctx: ChannelHandlerContext, msg: ChannelMessage?) {
        val obj = SerializableTool.ByteArrayToObject(msg?.byteArray)
        when (msg?.dataType) {
            DataType.BINARY -> {
//                println("BINARY")
            }
            DataType.OFFLINE -> {
//                println("OFFLINE")
            }
            DataType.ONLINE -> {
//                println("ONLINE")
                id = obj as OnLineMessage
                users[id] = ctx.channel()  //将在线用户添加进在线用户列表
//                println(id)
            }
            DataType.TEXT -> {
                val textMessage = obj as TextMessage
                chatServiceImpl.save(
                    Chat(
                        id1 = textMessage.from,
                        id2 = textMessage.to,
                        text = textMessage.text
                    )
                )  //存数据库
                sendMessage(
                    textMessage.from,
                    textMessage.to,
                    textMessage.text
                )                                    //在信道发送消息
//                println("TEXT")
//                println(textMessage)
            }
            DataType.HEARTBEAT -> {
//                println("HEARTBEAT")
                val value = obj as HeartbeatMessage
//                println(value)
                value.ip = "localhost"
                value.networkType = NetWorkType.NULL
                val array = SerializableTool.ObjectToByteArray(value)
                ctx.writeAndFlush(ChannelMessage(array.size, DataType.HEARTBEAT, array))
            }
        }
    }

    override fun channelActive(ctx: ChannelHandlerContext?) {
        channelGroup.add(ctx?.channel())
//        println("新增用户")
    }

    override fun channelInactive(ctx: ChannelHandlerContext?) {
        channelGroup.remove(ctx?.channel())
        users.remove(id)
//        println("移除用户 $id")
    }

    override fun exceptionCaught(ctx: ChannelHandlerContext?, cause: Throwable) {
        ctx?.channel()?.close()
//        println("有连接强制断开 caused by ${cause.message}")
    }

    //发送消息
    private fun sendMessage(id1: String, id2: String, text: String) {
        users.forEach { (t, u) ->
            if (id2 == t.id) {
                val message = TextMessage(from = id1, to = id2, text = text, time = LocalDateTime.now())
                val objectToByteArray = SerializableTool.ObjectToByteArray(message)
                u.writeAndFlush(ChannelMessage(objectToByteArray.size, DataType.TEXT, objectToByteArray))
                return@forEach
            }
        }
    }
}